home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
- // r_main.c
- #include "r_local.h"
-
- void R_Clear (void);
-
- viddef_t vid;
-
- int GL_TEXTURE0, GL_TEXTURE1;
-
- model_t *r_worldmodel;
-
- float gldepthmin, gldepthmax;
-
- glconfig_t gl_config;
- glstate_t gl_state;
-
- image_t *r_notexture; // use for bad textures
- image_t *r_particletexture; // little dot for particles
- image_t *r_smoketexture; // for smoke, etc...
- image_t *r_explosiontexture;
- image_t *r_bloodtexture;
- image_t *r_pufftexture;
- image_t *r_blastertexture;
- image_t *r_bflashtexture;
- image_t *r_leaderfieldtexture;
- image_t *r_shelltexture; // c14 added shell texture
-
- entity_t *currententity;
- model_t *currentmodel;
-
- cplane_t frustum[4];
-
- int r_visframecount; // bumped when going to a new PVS
- int r_framecount; // used for dlight push checking
-
- int c_brush_polys, c_alias_polys;
-
- float v_blend[4]; // final blending color
-
- gparticle_t gparticles[MAX_PARTICLES];
- int num_gparticles;
-
- void GL_Strings_f( void );
-
- //
- // view origin
- //
- vec3_t vup;
- vec3_t vpn;
- vec3_t vright;
- vec3_t r_origin;
-
- float r_world_matrix[16];
-
- //
- // screen size info
- //
- refdef_t r_newrefdef;
-
- int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
-
- cvar_t *r_norefresh;
- cvar_t *r_drawentities;
- cvar_t *r_drawworld;
- cvar_t *r_speeds;
- cvar_t *r_fullbright;
- cvar_t *r_novis;
- cvar_t *r_nocull;
- cvar_t *r_lerpmodels;
- cvar_t *r_lefthand;
-
- cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level
-
- cvar_t *gl_nosubimage;
- cvar_t *gl_allow_software;
-
- cvar_t *gl_vertex_arrays;
-
- cvar_t *gl_particle_min_size;
- cvar_t *gl_particle_max_size;
- cvar_t *gl_particle_size;
- cvar_t *gl_particle_att_a;
- cvar_t *gl_particle_att_b;
- cvar_t *gl_particle_att_c;
-
- cvar_t *gl_ext_swapinterval;
- cvar_t *gl_ext_palettedtexture;
- cvar_t *gl_ext_multitexture;
- cvar_t *gl_ext_pointparameters;
- cvar_t *gl_ext_compiled_vertex_array;
-
- cvar_t *gl_log;
- cvar_t *gl_bitdepth;
- cvar_t *gl_drawbuffer;
- cvar_t *gl_driver;
- cvar_t *gl_lightmap;
- cvar_t *gl_shadows;
- cvar_t *gl_mode;
- cvar_t *gl_dynamic;
- cvar_t *gl_monolightmap;
- cvar_t *gl_modulate;
- cvar_t *gl_nobind;
- cvar_t *gl_round_down;
- cvar_t *gl_picmip;
- cvar_t *gl_skymip;
- cvar_t *gl_showtris;
- cvar_t *gl_finish;
- cvar_t *gl_clear;
- cvar_t *gl_cull;
- cvar_t *gl_polyblend;
- cvar_t *gl_flashblend;
- cvar_t *gl_playermip;
- cvar_t *gl_saturatelighting;
- cvar_t *gl_swapinterval;
- cvar_t *gl_texturemode;
- cvar_t *gl_texturealphamode;
- cvar_t *gl_texturesolidmode;
- cvar_t *gl_lockpvs;
-
- cvar_t *gl_3dlabs_broken;
-
- cvar_t *vid_fullscreen;
- cvar_t *vid_gamma;
- cvar_t *vid_ref;
-
-
- void R_AddGlowEffect (float red, float green, float blue, float radius, vec3_t origin);
-
-
- // glow definitions - originally from gl_rmain.c
- #define MAX_GLOWS 2048
- int num_glows;
-
- typedef struct glows_s
- {
- float red;
- float green;
- float blue;
- float radius;
- vec3_t origin;
- } glows_t;
-
- glows_t glow_effects[MAX_GLOWS];
-
- // sin and cos tables from 0 to 1 in 0.0625 increments to speed up glow rendering
- // also from gl_rmisc.c and externed in gl_quake.h - i also use them for alias model glows.
- float glowcos[17] =
- {
- 1.000000,
- 0.923879,
- 0.707106,
- 0.382682,
- -0.000002,
- -0.382686,
- -0.707109,
- -0.923881,
- -1.000000,
- -0.923878,
- -0.707103,
- -0.382678,
- 0.000006,
- 0.382689,
- 0.707112,
- 0.923882,
- 1.000000,
- };
-
-
- float glowsin[17] =
- {
- 0.000000,
- 0.382684,
- 0.707107,
- 0.923880,
- 1.000000,
- 0.923879,
- 0.707105,
- 0.382680,
- -0.000004,
- -0.382687,
- -0.707110,
- -0.923882,
- -1.000000,
- -0.923877,
- -0.707102,
- -0.382677,
- 0.000008,
- };
-
-
- // this prototype was not required in my original engine
- void R_RenderGlowEffects (void);
-
- /*
- =================
- R_CullBox
-
- Returns true if the box is completely outside the frustom
- =================
- */
- qboolean R_CullBox (vec3_t mins, vec3_t maxs)
- {
- int i;
-
- if (r_nocull->value)
- return false;
-
- for (i=0 ; i<4 ; i++)
- if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
- return true;
- return false;
- }
-
-
- void R_RotateForEntity (entity_t *e)
- {
- qglTranslatef (e->origin[0], e->origin[1], e->origin[2]);
-
- qglRotatef (e->angles[1], 0, 0, 1);
- qglRotatef (-e->angles[0], 0, 1, 0);
- qglRotatef (-e->angles[2], 1, 0, 0);
- }
-
- /*
- =============================================================
-
- SPRITE MODELS
-
- =============================================================
- */
-
-
- /*
- =================
- R_DrawSpriteModel
-
- =================
- */
- void R_DrawSpriteModel (entity_t *e)
- {
- float alpha = 1.0F;
- vec3_t point;
- vec3_t v_forward, v_right, v_up;
- dsprframe_t *frame;
- float *up, *right;
- dsprite_t *psprite;
-
- // don't even bother culling, because it's just a single
- // polygon without a surface cache
-
- psprite = (dsprite_t *)currentmodel->extradata;
-
- e->frame %= psprite->numframes;
-
- frame = &psprite->frames[e->frame];
-
- AngleVectors (currententity->angles, v_forward, v_right, v_up);
- up = v_forward;
- right = v_right;
-
- GL_Bind (currentmodel->skins[e->frame]->texnum);
-
- alpha = 0.6;
- qglDepthMask( GL_FALSE );
- qglEnable( GL_BLEND );
- qglBlendFunc (GL_SRC_ALPHA, GL_ONE);
- GL_TexEnv( GL_MODULATE );
- qglBegin (GL_QUADS);
-
- qglColor4f( 1, 1, 1, alpha );
-
- qglTexCoord2f (0, 1);
- VectorMA (e->origin, -frame->origin_y, up, point);
- VectorMA (point, -frame->origin_x, right, point);
- qglVertex3fv (point);
-
- qglTexCoord2f (0, 0);
- VectorMA (e->origin, frame->height - frame->origin_y, up, point);
- VectorMA (point, -frame->origin_x, right, point);
- qglVertex3fv (point);
-
- qglTexCoord2f (1, 0);
- VectorMA (e->origin, frame->height - frame->origin_y, up, point);
- VectorMA (point, frame->width - frame->origin_x, right, point);
- qglVertex3fv (point);
-
- qglTexCoord2f (1, 1);
- VectorMA (e->origin, -frame->origin_y, up, point);
- VectorMA (point, frame->width - frame->origin_x, right, point);
- qglVertex3fv (point);
-
- qglEnd ();
-
- qglDisable (GL_ALPHA_TEST);
- GL_TexEnv( GL_REPLACE );
- qglDisable( GL_BLEND );
- qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- qglDepthMask( 1 );
- qglColor4f( 1, 1, 1, 1 );
- }
-
- //==================================================================================
-
- /*
- =============
- R_DrawNullModel
- =============
- */
- void R_DrawNullModel (void)
- {
- vec3_t shadelight;
- int i;
-
- if ( currententity->flags & RF_FULLBRIGHT )
- shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
- else
- R_LightPoint (currententity->origin, shadelight);
-
- qglPushMatrix ();
- R_RotateForEntity (currententity);
-
- qglDisable (GL_TEXTURE_2D);
- qglColor3fv (shadelight);
-
- qglBegin (GL_TRIANGLE_FAN);
- qglVertex3f (0, 0, -16);
- for (i=0 ; i<=4 ; i++)
- qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
- qglEnd ();
-
- qglBegin (GL_TRIANGLE_FAN);
- qglVertex3f (0, 0, 16);
- for (i=4 ; i>=0 ; i--)
- qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
- qglEnd ();
-
- qglColor3f (1,1,1);
- qglPopMatrix ();
- qglEnable (GL_TEXTURE_2D);
- }
-
- /*
- =============
- R_DrawEntitiesOnList
- =============
- */
- void R_DrawEntitiesOnList (void)
- {
- int i;
-
- if (!r_drawentities->value)
- return;
-
- // draw non-transparent first
- for (i=0 ; i<r_newrefdef.num_entities ; i++)
- {
- currententity = &r_newrefdef.entities[i];
- if (currententity->flags & RF_TRANSLUCENT)
- continue; // solid
-
- if ( currententity->flags & RF_BEAM )
- {
- R_DrawBeam( currententity );
- }
- else
- {
- currentmodel = currententity->model;
- if (!currentmodel)
- {
- R_DrawNullModel ();
- continue;
- }
- switch (currentmodel->type)
- {
- case mod_alias:
- R_DrawAliasModel (currententity);
- break;
- case mod_brush:
- R_DrawBrushModel (currententity);
- break;
- case mod_sprite:
- R_DrawSpriteModel (currententity);
- break;
- default:
- Com_Error(ERR_DROP, "Bad modeltype");
- break;
- }
- }
- }
-
- // draw transparent entities
- // we could sort these if it ever becomes a problem...
- qglDepthMask (0); // no z writes
- for (i=0 ; i<r_newrefdef.num_entities ; i++)
- {
- currententity = &r_newrefdef.entities[i];
- if (!(currententity->flags & RF_TRANSLUCENT))
- continue; // solid
-
- if ( currententity->flags & RF_BEAM )
- {
- R_DrawBeam( currententity );
- }
- else
- {
- currentmodel = currententity->model;
-
- if (!currentmodel)
- {
- R_DrawNullModel ();
- continue;
- }
- switch (currentmodel->type)
- {
- case mod_alias:
- R_DrawAliasModel (currententity);
- break;
- case mod_brush:
- R_DrawBrushModel (currententity);
- break;
- case mod_sprite:
- R_DrawSpriteModel (currententity);
- break;
- default:
- Com_Error (ERR_DROP, "Bad modeltype");
- break;
- }
- }
- }
- qglDepthMask (1); // back to writing
-
- }
-
- /*
- ** GL_DrawParticles
- **
- */
- void GL_DrawParticles( int num_particles, gparticle_t particles[], const unsigned colortable[768])
- {
- const gparticle_t *p;
- int i;
- vec3_t corner[4], up, right, pup, pright;
- float scale;
- byte color[4], oldcolor[4];
- int oldtype;
- int texnum, blenddst, blendsrc;
- float *corner0 = corner[0];
-
- if ( !num_particles )
- return;
-
- qglDepthMask( GL_FALSE ); // no z buffering
- qglEnable( GL_BLEND);
- GL_TexEnv( GL_MODULATE );
-
- for ( p = particles, i=0, oldtype=-1 ; i < num_particles ; i++,p++)
- {
- switch (p->type)
- {
- case PARTICLE_EXPLOSION:
- texnum = r_explosiontexture->texnum;
- scale = 4 + (rand()&7);
- *(int *)color = colortable[0xe0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_GREEN_BLOOD:
- texnum = r_bloodtexture->texnum;
- scale = 3;
- *(int *)color = colortable[0xd0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_BLASTER:
- texnum = r_blastertexture->texnum;
- scale = 4 + (rand()&7);
- *(int *)color = colortable[0xe0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_BLOOD:
- texnum = r_bloodtexture->texnum;
- scale = 3;
- *(int *)color = colortable[0xe8];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_GUNSHOT:
- texnum = r_pufftexture->texnum;
- scale = 4 + (rand()&2);
- *(int *)color = colortable[15];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_HEATBEAM:
- texnum = r_particletexture->texnum;
- scale = 5 + (rand()&2);
- *(int *)color = colortable[0xe0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_SMOKE2:
- texnum = r_smoketexture->texnum;
- scale = 6 + (rand()&7);
- *(int *)color = colortable[15];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_SMOKE:
- texnum = r_smoketexture->texnum;
- scale = 3;
- *(int *)color = colortable[15];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE_MINUS_SRC_ALPHA;
- break;
-
- case PARTICLE_GREEN_LASER1:
- texnum = r_blastertexture->texnum;
- scale = .2 + (rand()&7);
- *(int *)color = colortable[0xd0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_LEADER_BLAST:
- texnum = r_blastertexture->texnum;
- scale = 2 + (rand()&7);
- *(int *)color = colortable[0xe8];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_GREEN_LASER2:
- texnum = r_blastertexture->texnum;
- scale = .1 + (rand()&5);
- *(int *)color = colortable[66];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_BLASTER_MZFLASH:
- texnum = r_bflashtexture->texnum;
- scale = 8 + (rand()&7);
- *(int *)color = colortable[0xe0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_LEADER_FIELD:
- texnum = r_leaderfieldtexture->texnum;
- // scale = scale + 24 + (rand()&2); // Vic: ???
- scale = 24 + (rand()&2);
- *(int *)color = colortable[0xff];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_STEAM:
- texnum = r_pufftexture->texnum;
- scale = 4 + (rand()&2);
- *(int *)color = colortable[15];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_LIGHTNING:
- texnum = r_particletexture->texnum;
- scale = 1 + (rand()&2);
- *(int *)color = colortable[0xff];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_BLASTER_BEAM:
- texnum = r_particletexture->texnum;
- scale = 1;
- *(int *)color = colortable[0xe0];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- case PARTICLE_NONE:
- texnum = r_particletexture->texnum;
- scale = 1;
- *(int *)color = colortable[p->color];
- blendsrc = GL_SRC_ALPHA;
- blenddst = GL_ONE;
- break;
-
- default:
- Com_Printf ( "Unknown particle type: %i\n", p->type);
- break;
- }
-
- color[3] = p->alpha*255;
-
- if (
- p->type != oldtype
- || color[0] != oldcolor[0] || color[1] != oldcolor[1]
- || color[2] != oldcolor[2] || color[3] != oldcolor[3] )
- {
- if ( oldtype != -1 )
- {
- qglEnd ();
- }
-
- if ( scale != 1 )
- {
- VectorScale (vup, scale, up);
- VectorScale (vright, scale, right);
- }
- else
- {
- VectorCopy (vup, up);
- VectorCopy (vright, right);
- }
-
- oldtype = p->type;
- oldcolor[3] = color[3];
- VectorCopy ( color, oldcolor );
-
- GL_Bind ( texnum );
- qglBlendFunc ( blendsrc, blenddst );
- qglColor4ubv( color );
- qglBegin ( GL_QUADS );
- }
-
- VectorScale ( right, p->dist, pright );
- VectorScale ( up, p->dist, pup );
- VectorSet (corner[0],
- p->origin[0] + (pup[0] + pright[0])*(-0.5),
- p->origin[1] + (pup[1] + pright[1])*(-0.5),
- p->origin[2] + (pup[2] + pright[2])*(-0.5));
-
- VectorSet ( corner[1],
- corner0[0] + pup[0], corner0[1] + pup[1], corner0[2] + pup[2]);
- VectorSet ( corner[2], corner0[0] + (pup[0]+pright[0]),
- corner0[1] + (pup[1]+pright[1]), corner0[2] + (pup[2]+pright[2]));
- VectorSet ( corner[3],
- corner0[0] + pright[0], corner0[1] + pright[1], corner0[2] + pright[2]);
-
- qglTexCoord2f( 1, 1 );
- qglVertex3fv( corner[0] );
-
- qglTexCoord2f( 0, 1 );
- qglVertex3fv ( corner[1] );
-
- qglTexCoord2f( 0, 0 );
- qglVertex3fv ( corner[2] );
-
- qglTexCoord2f( 1, 0 );
- qglVertex3fv ( corner[3] );
- }
-
- qglEnd ();
- qglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- qglColor4f( 1,1,1,1 );
- qglDisable(GL_BLEND);
- qglDepthMask( GL_TRUE ); // back to normal Z buffering
- GL_TexEnv( GL_REPLACE );
- }
-
- /*
- ===============
- R_SortParticles
- ===============
- */
- #define R_CopyParticle(a,b) (a.type=b.type,a.alpha=b.alpha,a.color=b.color,a.dist=b.dist,VectorCopy(b.origin,a.origin))
-
- static void R_SortParticles (gparticle_t *particles, int Li, int Ri)
- {
- int pivot;
- gparticle_t temppart;
- int li, ri;
-
- mark0:
- li = Li;
- ri = Ri;
-
- pivot = particles[(Li+Ri) >> 1].type;
- while (li < ri)
- {
- while (particles[li].type < pivot) li++;
- while (particles[ri].type > pivot) ri--;
-
- if (li <= ri)
- {
- R_CopyParticle( temppart, particles[ri] );
- R_CopyParticle( particles[ri], particles[li] );
- R_CopyParticle( particles[li], temppart );
-
- li++;
- ri--;
- }
- }
-
- if ( Li < ri ) {
- R_SortParticles( particles, Li, ri );
- }
- if (li < Ri) {
- Li = li;
- goto mark0;
- }
- }
-
- /*
- ===============
- R_DrawParticles
- ===============
- */
- void R_DrawParticles (void)
- {
- int i;
- float dist;
- gparticle_t *gp;
- const particle_t *p;
-
- if ( !r_newrefdef.num_particles )
- return;
-
- gp = gparticles;
- num_gparticles = 0;
- for ( p = r_newrefdef.particles, i=0 ; i < r_newrefdef.num_particles ; i++,p++)
- {
- // hack a scale up to keep particles from disapearing
- dist = ( p->origin[0] - r_origin[0] ) * vpn[0] +
- ( p->origin[1] - r_origin[1] ) * vpn[1] +
- ( p->origin[2] - r_origin[2] ) * vpn[2];
-
- if (dist < 0)
- continue;
- else if (dist >= 40)
- dist = 2 + dist * 0.004;
- else
- dist = 2;
-
- gp->alpha = p->alpha;
- gp->color = p->color;
- gp->type = p->type;
- gp->dist = dist;
- VectorCopy ( p->origin, gp->origin );
-
- gp++;
- num_gparticles++;
- }
-
- R_SortParticles ( gparticles, 0, num_gparticles - 1 );
-
- // we are always going to used textured particles!
- GL_DrawParticles( num_gparticles, gparticles, d_8to24table);
- }
-
- /*
- ============
- R_PolyBlend
- ============
- */
- void R_PolyBlend (void)
- {
- if (!gl_polyblend->value)
- return;
- if (!v_blend[3])
- return;
-
- qglDisable (GL_ALPHA_TEST);
- qglEnable (GL_BLEND);
- qglDisable (GL_DEPTH_TEST);
- qglDisable (GL_TEXTURE_2D);
-
- qglMatrixMode(GL_PROJECTION);
- qglLoadIdentity ();
- qglOrtho (0, 1, 1, 0, -99999, 99999);
-
- qglMatrixMode(GL_MODELVIEW);
- qglLoadIdentity ();
-
- qglColor4fv (v_blend);
-
- qglBegin (GL_TRIANGLES);
- qglVertex2f (-5, -5);
- qglVertex2f (10, -5);
- qglVertex2f (-5, 10);
- qglEnd ();
-
- qglDisable (GL_BLEND);
- qglEnable (GL_TEXTURE_2D);
- qglEnable (GL_ALPHA_TEST);
-
- qglColor4f(1,1,1,1);
- }
-
- //=======================================================================
-
- int SignbitsForPlane (cplane_t *out)
- {
- int bits, j;
-
- // for fast box on planeside test
-
- bits = 0;
- for (j=0 ; j<3 ; j++)
- {
- if (out->normal[j] < 0)
- bits |= 1<<j;
- }
- return bits;
- }
-
-
- void R_SetFrustum (void)
- {
- int i;
-
- // rotate VPN right by FOV_X/2 degrees
- RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) );
- // rotate VPN left by FOV_X/2 degrees
- RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 );
- // rotate VPN up by FOV_X/2 degrees
- RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 );
- // rotate VPN down by FOV_X/2 degrees
- RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) );
-
- for (i=0 ; i<4 ; i++)
- {
- frustum[i].type = PLANE_ANYZ;
- frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
- frustum[i].signbits = SignbitsForPlane (&frustum[i]);
- }
- }
-
- //=======================================================================
-
- /*
- ===============
- R_SetupFrame
- ===============
- */
- void R_SetupFrame (void)
- {
- int i;
- mleaf_t *leaf;
-
- r_framecount++;
-
- // build the transformation matrix for the given view angles
- VectorCopy (r_newrefdef.vieworg, r_origin);
-
- AngleVectors (r_newrefdef.viewangles, vpn, vright, vup);
-
- // current viewcluster
- if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
- {
- r_oldviewcluster = r_viewcluster;
- r_oldviewcluster2 = r_viewcluster2;
- leaf = Mod_PointInLeaf (r_origin, r_worldmodel);
- r_viewcluster = r_viewcluster2 = leaf->cluster;
-
- // check above and below so crossing solid water doesn't draw wrong
- if (!leaf->contents)
- { // look down a bit
- vec3_t temp;
-
- VectorCopy (r_origin, temp);
- temp[2] -= 16;
- leaf = Mod_PointInLeaf (temp, r_worldmodel);
- if ( !(leaf->contents & CONTENTS_SOLID) &&
- (leaf->cluster != r_viewcluster2) )
- r_viewcluster2 = leaf->cluster;
- }
- else
- { // look up a bit
- vec3_t temp;
-
- VectorCopy (r_origin, temp);
- temp[2] += 16;
- leaf = Mod_PointInLeaf (temp, r_worldmodel);
- if ( !(leaf->contents & CONTENTS_SOLID) &&
- (leaf->cluster != r_viewcluster2) )
- r_viewcluster2 = leaf->cluster;
- }
- }
-
- for (i=0 ; i<4 ; i++)
- v_blend[i] = r_newrefdef.blend[i];
-
- c_brush_polys = 0;
- c_alias_polys = 0;
-
- // clear out the portion of the screen that the NOWORLDMODEL defines
- if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
- {
- qglEnable( GL_SCISSOR_TEST );
- qglClearColor( 0.3, 0.3, 0.3, 1 );
- qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
- qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- qglClearColor( 1, 0, 0.5, 0.5 );
- qglDisable( GL_SCISSOR_TEST );
- }
- }
-
-
- void MYgluPerspective( GLdouble fovy, GLdouble aspect,
- GLdouble zNear, GLdouble zFar )
- {
- GLdouble xmin, xmax, ymin, ymax;
-
- ymax = zNear * tan( fovy * M_PI / 360.0 );
- ymin = -ymax;
-
- xmin = ymin * aspect;
- xmax = ymax * aspect;
-
- xmin += -( 2 * gl_state.camera_separation ) / zNear;
- xmax += -( 2 * gl_state.camera_separation ) / zNear;
-
- qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
- }
-
-
- /*
- =============
- R_SetupGL
- =============
- */
- void R_SetupGL (void)
- {
- float screenaspect;
- int x, x2, y2, y, w, h;
-
- //
- // set up viewport
- //
- x = floor(r_newrefdef.x * vid.width / vid.width);
- x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
- y = floor(vid.height - r_newrefdef.y * vid.height / vid.height);
- y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
-
- w = x2 - x;
- h = y - y2;
-
- qglViewport (x, y2, w, h);
-
- //
- // set up projection matrix
- //
- screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
- qglMatrixMode(GL_PROJECTION);
- qglLoadIdentity ();
- MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 128000);
-
- qglCullFace(GL_FRONT);
-
- qglMatrixMode(GL_MODELVIEW);
- qglLoadIdentity ();
-
- qglRotatef (-90, 1, 0, 0); // put Z going up
- qglRotatef (90, 0, 0, 1); // put Z going up
- qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0);
- qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0);
- qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1);
- qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
-
- // if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
- // qglTranslatef ( gl_state.camera_separation, 0, 0 );
-
- qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
-
- //
- // set drawing parms
- //
- if (gl_cull->value)
- qglEnable(GL_CULL_FACE);
- else
- qglDisable(GL_CULL_FACE);
-
- // CDawg - start
- if (r_newrefdef.viewangles[2])
- qglEnable(GL_BLEND);
- else
- qglDisable(GL_BLEND);
- // CDawg - end
-
- //qglDisable(GL_BLEND); //CDawg <-- comment this line.
-
- qglDisable(GL_ALPHA_TEST);
- qglEnable(GL_DEPTH_TEST);
- }
-
- /*
- =============
- R_Clear
- =============
- */
- void R_Clear (void)
- {
- if (gl_clear->value)
- qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- else
- qglClear (GL_DEPTH_BUFFER_BIT);
-
- gldepthmin = 0;
- gldepthmax = 1;
- qglDepthFunc (GL_LEQUAL);
-
- qglDepthRange (gldepthmin, gldepthmax);
-
- }
-
- void R_Flash( void )
- {
- R_PolyBlend ();
- }
-
- /*
- ================
- R_RenderView
-
- r_newrefdef must be set before the first call
- ================
- */
- void R_RenderView (refdef_t *fd)
- {
-
- GLfloat colors[4] = {(GLfloat) 0.3, (GLfloat) 0.3, (GLfloat) 0.3, (GLfloat) 0.1};
-
- if (r_norefresh->value)
- return;
-
- r_newrefdef = *fd;
-
- if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
- Com_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
-
- if (r_speeds->value)
- {
- c_brush_polys = 0;
- c_alias_polys = 0;
- }
-
-
- R_PushDlights ();
- R_PushStains ();
-
- if (gl_finish->value)
- qglFinish ();
-
- R_SetupFrame ();
-
- R_SetFrustum ();
-
- R_SetupGL ();
-
- R_MarkLeaves (); // done here so we know if we're in water
-
- //qglFogi(GL_FOG_MODE, GL_LINEAR);
- //qglFogfv(GL_FOG_COLOR, colors);
- //qglFogf(GL_FOG_START, 50.0);
- //qglFogf(GL_FOG_END, 1500.0);
- //qglFogf(GL_FOG_DENSITY, 0.02);
- //qglEnable(GL_FOG);
-
- R_DrawWorld ();
-
- R_DrawEntitiesOnList ();
-
- R_DrawAlphaSurfaces ();
-
- R_RenderDlights ();
-
- R_DrawParticles ();
-
- R_Flash();
-
- if (r_speeds->value)
- {
- Com_Printf ( "%4i wpoly %4i epoly %i tex %i lmaps\n",
- c_brush_polys,
- c_alias_polys,
- c_visible_textures,
- c_visible_lightmaps);
- }
- //qglDisable(GL_FOG);
- }
-
-
- void R_SetGL2D (void)
- {
- // set 2D virtual screen size
- qglViewport (0,0, vid.width, vid.height);
- qglMatrixMode(GL_PROJECTION);
- qglLoadIdentity ();
- qglOrtho (0, vid.width, vid.height, 0, -99999, 99999);
- qglMatrixMode(GL_MODELVIEW);
- qglLoadIdentity ();
- qglDisable (GL_DEPTH_TEST);
- qglDisable (GL_CULL_FACE);
- qglDisable (GL_BLEND);
- qglEnable (GL_ALPHA_TEST);
- qglColor4f (1,1,1,1);
- }
-
- static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y )
- {
- qglColor3f( r, g, b );
- qglVertex2f( 0, y );
- qglVertex2f( vid.width, y );
- qglColor3f( 0, 0, 0 );
- qglVertex2f( 0, y + 1 );
- qglVertex2f( vid.width, y + 1 );
- }
-
- static void GL_DrawStereoPattern( void )
- {
- int i;
-
- if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) )
- return;
-
- if ( !gl_state.stereo_enabled )
- return;
-
- R_SetGL2D();
-
- qglDrawBuffer( GL_BACK_LEFT );
-
- for ( i = 0; i < 20; i++ )
- {
- qglBegin( GL_LINES );
- GL_DrawColoredStereoLinePair( 1, 0, 0, 0 );
- GL_DrawColoredStereoLinePair( 1, 0, 0, 2 );
- GL_DrawColoredStereoLinePair( 1, 0, 0, 4 );
- GL_DrawColoredStereoLinePair( 1, 0, 0, 6 );
- GL_DrawColoredStereoLinePair( 0, 1, 0, 8 );
- GL_DrawColoredStereoLinePair( 1, 1, 0, 10);
- GL_DrawColoredStereoLinePair( 1, 1, 0, 12);
- GL_DrawColoredStereoLinePair( 0, 1, 0, 14);
- qglEnd();
-
- GLimp_EndFrame();
- }
- }
-
-
- /*
- ====================
- R_SetLightLevel
-
- ====================
- */
- void R_SetLightLevel (void)
- {
- vec3_t shadelight;
-
- if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
- return;
-
- // save off light value for server to look at (BIG HACK!)
-
- R_LightPoint (r_newrefdef.vieworg, shadelight);
-
- // pick the greatest component, which should be the same
- // as the mono value returned by software
- if (shadelight[0] > shadelight[1])
- {
- if (shadelight[0] > shadelight[2])
- r_lightlevel->value = 150*shadelight[0];
- else
- r_lightlevel->value = 150*shadelight[2];
- }
- else
- {
- if (shadelight[1] > shadelight[2])
- r_lightlevel->value = 150*shadelight[1];
- else
- r_lightlevel->value = 150*shadelight[2];
- }
-
- }
-
- /*
- @@@@@@@@@@@@@@@@@@@@@
- R_RenderFrame
-
- @@@@@@@@@@@@@@@@@@@@@
- */
- void R_RenderFrame (refdef_t *fd)
- {
- R_RenderView( fd );
- R_SetLightLevel ();
- R_SetGL2D ();
- }
-
-
- void R_Register( void )
- {
- r_lefthand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
- r_norefresh = Cvar_Get ("r_norefresh", "0", 0);
- r_fullbright = Cvar_Get ("r_fullbright", "0", 0);
- r_drawentities = Cvar_Get ("r_drawentities", "1", 0);
- r_drawworld = Cvar_Get ("r_drawworld", "1", 0);
- r_novis = Cvar_Get ("r_novis", "0", 0);
- r_nocull = Cvar_Get ("r_nocull", "0", 0);
- r_lerpmodels = Cvar_Get ("r_lerpmodels", "1", 0);
- r_speeds = Cvar_Get ("r_speeds", "0", 0);
-
- r_lightlevel = Cvar_Get ("r_lightlevel", "0", 0);
-
- gl_nosubimage = Cvar_Get( "gl_nosubimage", "0", 0 );
- gl_allow_software = Cvar_Get( "gl_allow_software", "0", 0 );
-
- gl_particle_min_size = Cvar_Get( "gl_particle_min_size", "2", CVAR_ARCHIVE );
- gl_particle_max_size = Cvar_Get( "gl_particle_max_size", "40", CVAR_ARCHIVE );
- gl_particle_size = Cvar_Get( "gl_particle_size", "40", CVAR_ARCHIVE );
- gl_particle_att_a = Cvar_Get( "gl_particle_att_a", "0.01", CVAR_ARCHIVE );
- gl_particle_att_b = Cvar_Get( "gl_particle_att_b", "0.0", CVAR_ARCHIVE );
- gl_particle_att_c = Cvar_Get( "gl_particle_att_c", "0.01", CVAR_ARCHIVE );
-
- gl_modulate = Cvar_Get ("gl_modulate", "2", CVAR_ARCHIVE );
- gl_log = Cvar_Get( "gl_log", "0", 0 );
- gl_bitdepth = Cvar_Get( "gl_bitdepth", "0", 0 );
- gl_mode = Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE );
- gl_lightmap = Cvar_Get ("gl_lightmap", "0", 0);
- gl_shadows = Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE );
- gl_dynamic = Cvar_Get ("gl_dynamic", "1", 0);
- gl_nobind = Cvar_Get ("gl_nobind", "0", 0);
- gl_round_down = Cvar_Get ("gl_round_down", "1", 0);
- gl_picmip = Cvar_Get ("gl_picmip", "0", 0);
- gl_skymip = Cvar_Get ("gl_skymip", "0", 0);
- gl_showtris = Cvar_Get ("gl_showtris", "0", 0);
- gl_finish = Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE);
- gl_clear = Cvar_Get ("gl_clear", "0", 0);
- gl_cull = Cvar_Get ("gl_cull", "1", 0);
- gl_polyblend = Cvar_Get ("gl_polyblend", "1", 0);
- gl_flashblend = Cvar_Get ("gl_flashblend", "0", 0);
- gl_playermip = Cvar_Get ("gl_playermip", "0", 0);
- gl_monolightmap = Cvar_Get( "gl_monolightmap", "0", 0 );
- gl_driver = Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE );
- gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
- gl_texturealphamode = Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
- gl_texturesolidmode = Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );
- gl_lockpvs = Cvar_Get( "gl_lockpvs", "0", 0 );
-
- gl_vertex_arrays = Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE );
-
- gl_ext_swapinterval = Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE );
- gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "0", CVAR_ARCHIVE );
- gl_ext_multitexture = Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE );
- gl_ext_pointparameters = Cvar_Get( "gl_ext_pointparameters", "0", CVAR_ARCHIVE );
- gl_ext_compiled_vertex_array = Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
-
- gl_drawbuffer = Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
- gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE );
-
- gl_saturatelighting = Cvar_Get( "gl_saturatelighting", "0", 0 );
-
- gl_3dlabs_broken = Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE );
-
- vid_fullscreen = Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
- vid_gamma = Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
- vid_ref = Cvar_Get( "vid_ref", "gl", CVAR_ARCHIVE );
-
- Cmd_AddCommand( "imagelist", GL_ImageList_f );
- Cmd_AddCommand( "screenshot", GL_ScreenShot_f );
- Cmd_AddCommand( "modellist", Mod_Modellist_f );
- Cmd_AddCommand( "gl_strings", GL_Strings_f );
- }
-
- /*
- ==================
- R_SetMode
- ==================
- */
- qboolean R_SetMode (void)
- {
- rserr_t err;
- qboolean fullscreen;
-
- if ( vid_fullscreen->modified && !gl_config.allow_cds )
- {
- Com_Printf ("R_SetMode() - CDS not allowed with this driver\n" );
- Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
- vid_fullscreen->modified = false;
- }
-
- fullscreen = vid_fullscreen->value;
-
- vid_fullscreen->modified = false;
- gl_mode->modified = false;
-
- if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok )
- {
- gl_state.prev_mode = gl_mode->value;
- }
- else
- {
- if ( err == rserr_invalid_fullscreen )
- {
- Cvar_SetValue( "vid_fullscreen", 0);
- vid_fullscreen->modified = false;
- Com_Printf ("ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" );
- if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok )
- return true;
- }
- else if ( err == rserr_invalid_mode )
- {
- Cvar_SetValue( "gl_mode", gl_state.prev_mode );
- gl_mode->modified = false;
- Com_Printf ("ref_gl::R_SetMode() - invalid mode\n" );
- }
-
- // try setting it back to something safe
- if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok )
- {
- Com_Printf ("ref_gl::R_SetMode() - could not revert to safe mode\n" );
- return false;
- }
- }
- return true;
- }
-
- /*
- ===============
- R_Init
- ===============
- */
- int R_Init( void *hinstance, void *hWnd )
- {
- char renderer_buffer[1000];
- char vendor_buffer[1000];
- int err;
- int j;
- extern float r_turbsin[256];
-
- for ( j = 0; j < 256; j++ )
- {
- r_turbsin[j] *= 0.5;
- }
-
- Com_Printf ("ref_gl version: "REF_VERSION"\n");
-
- Draw_GetPalette ();
-
- R_Register();
-
- // initialize our QGL dynamic bindings
- if ( !QGL_Init( gl_driver->string ) )
- {
- QGL_Shutdown();
- Com_Printf ("ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string );
- return -1;
- }
-
- // initialize OS-specific parts of OpenGL
- if ( !GLimp_Init( hinstance, hWnd ) )
- {
- QGL_Shutdown();
- return -1;
- }
-
- // set our "safe" modes
- gl_state.prev_mode = 3;
-
- // create the window and set up the context
- if ( !R_SetMode () )
- {
- QGL_Shutdown();
- Com_Printf ("ref_gl::R_Init() - could not R_SetMode()\n" );
- return -1;
- }
-
- VID_MenuInit();
-
- /*
- ** get our various GL strings
- */
- gl_config.vendor_string = qglGetString (GL_VENDOR);
- Com_Printf ("GL_VENDOR: %s\n", gl_config.vendor_string );
- gl_config.renderer_string = qglGetString (GL_RENDERER);
- Com_Printf ("GL_RENDERER: %s\n", gl_config.renderer_string );
- gl_config.version_string = qglGetString (GL_VERSION);
- Com_Printf ("GL_VERSION: %s\n", gl_config.version_string );
- gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
- Com_Printf ("GL_EXTENSIONS: %s\n", gl_config.extensions_string );
-
- strcpy( renderer_buffer, gl_config.renderer_string );
- strlwr( renderer_buffer );
-
- strcpy( vendor_buffer, gl_config.vendor_string );
- strlwr( vendor_buffer );
-
- if ( strstr( renderer_buffer, "voodoo" ) )
- {
- if ( !strstr( renderer_buffer, "rush" ) )
- gl_config.renderer = GL_RENDERER_VOODOO;
- else
- gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
- }
- else if ( strstr( vendor_buffer, "sgi" ) )
- gl_config.renderer = GL_RENDERER_SGI;
- else if ( strstr( renderer_buffer, "permedia" ) )
- gl_config.renderer = GL_RENDERER_PERMEDIA2;
- else if ( strstr( renderer_buffer, "glint" ) )
- gl_config.renderer = GL_RENDERER_GLINT_MX;
- else if ( strstr( renderer_buffer, "glzicd" ) )
- gl_config.renderer = GL_RENDERER_REALIZM;
- else if ( strstr( renderer_buffer, "gdi" ) )
- gl_config.renderer = GL_RENDERER_MCD;
- else if ( strstr( renderer_buffer, "pcx2" ) )
- gl_config.renderer = GL_RENDERER_PCX2;
- else if ( strstr( renderer_buffer, "verite" ) )
- gl_config.renderer = GL_RENDERER_RENDITION;
- else
- gl_config.renderer = GL_RENDERER_OTHER;
-
- if ( toupper( gl_monolightmap->string[1] ) != 'F' )
- {
- if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 )
- {
- Cvar_Set( "gl_monolightmap", "A" );
- Com_Printf ("...using gl_monolightmap 'a'\n" );
- }
- else if ( gl_config.renderer & GL_RENDERER_POWERVR )
- {
- Cvar_Set( "gl_monolightmap", "0" );
- }
- else
- {
- Cvar_Set( "gl_monolightmap", "0" );
- }
- }
-
- // power vr can't have anything stay in the framebuffer, so
- // the screen needs to redraw the tiled background every frame
- if ( gl_config.renderer & GL_RENDERER_POWERVR )
- {
- Cvar_Set( "scr_drawall", "1" );
- }
- else
- {
- Cvar_Set( "scr_drawall", "0" );
- }
-
- #ifdef __linux__
- Cvar_SetValue( "gl_finish", 1 );
- #endif
-
- // MCD has buffering issues
- if ( gl_config.renderer == GL_RENDERER_MCD )
- {
- Cvar_SetValue( "gl_finish", 1 );
- }
-
- if ( gl_config.renderer & GL_RENDERER_3DLABS )
- {
- if ( gl_3dlabs_broken->value )
- gl_config.allow_cds = false;
- else
- gl_config.allow_cds = true;
- }
- else
- {
- gl_config.allow_cds = true;
- }
-
- if ( gl_config.allow_cds )
- Com_Printf ("...allowing CDS\n" );
- else
- Com_Printf ( "...disabling CDS\n" );
-
- /*
- ** grab extensions
- */
- if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) ||
- strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) )
- {
- Com_Printf ("...enabling GL_EXT_compiled_vertex_array\n" );
- qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
- qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
- }
- else
- {
- Com_Printf ("...GL_EXT_compiled_vertex_array not found\n" );
- }
-
- #ifdef _WIN32
- if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
- {
- qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
- Com_Printf ("...enabling WGL_EXT_swap_control\n" );
- }
- else
- {
- Com_Printf ("...WGL_EXT_swap_control not found\n" );
- }
- #endif
-
- if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) )
- {
- if ( gl_ext_pointparameters->value )
- {
- qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
- qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
- Com_Printf ("...using GL_EXT_point_parameters\n" );
- }
- else
- {
- Com_Printf ("...ignoring GL_EXT_point_parameters\n" );
- }
- }
- else
- {
- Com_Printf ("...GL_EXT_point_parameters not found\n" );
- }
-
- #ifdef __linux__
- if ( strstr( gl_config.extensions_string, "3DFX_set_global_palette" ))
- {
- if ( gl_ext_palettedtexture->value )
- {
- Com_Printf ("...using 3DFX_set_global_palette\n" );
- qgl3DfxSetPaletteEXT = ( void ( APIENTRY * ) (GLuint *) )qwglGetProcAddress( "gl3DfxSetPaletteEXT" );
- qglColorTableEXT = Fake_glColorTableEXT;
- }
- else
- {
- Com_Printf ("...ignoring 3DFX_set_global_palette\n" );
- }
- }
- else
- {
- Com_Printf ("...3DFX_set_global_palette not found\n" );
- }
- #endif
-
- if ( !qglColorTableEXT &&
- strstr( gl_config.extensions_string, "GL_EXT_paletted_texture" ) &&
- strstr( gl_config.extensions_string, "GL_EXT_shared_texture_palette" ) )
- {
- if ( gl_ext_palettedtexture->value )
- {
- Com_Printf ("...using GL_EXT_shared_texture_palette\n" );
- qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" );
- }
- else
- {
- Com_Printf ("...ignoring GL_EXT_shared_texture_palette\n" );
- }
- }
- else
- {
- Com_Printf ("...GL_EXT_shared_texture_palette not found\n" );
- }
-
- if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) )
- {
- if ( gl_ext_multitexture->value )
- {
- Com_Printf ("...using GL_ARB_multitexture\n" );
- qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMultiTexCoord2fARB" );
- qglActiveTextureARB = ( void * ) qwglGetProcAddress( "glActiveTextureARB" );
- qglClientActiveTextureARB = ( void * ) qwglGetProcAddress( "glClientActiveTextureARB" );
- GL_TEXTURE0 = GL_TEXTURE0_ARB;
- GL_TEXTURE1 = GL_TEXTURE1_ARB;
- }
- else
- {
- Com_Printf ("...ignoring GL_ARB_multitexture\n" );
- }
- }
- else
- {
- Com_Printf ("...GL_ARB_multitexture not found\n" );
- }
-
- if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) )
- {
- if ( qglActiveTextureARB )
- {
- Com_Printf ("...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" );
- }
- else if ( gl_ext_multitexture->value )
- {
- Com_Printf ("...using GL_SGIS_multitexture\n" );
- qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
- qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
- GL_TEXTURE0 = GL_TEXTURE0_SGIS;
- GL_TEXTURE1 = GL_TEXTURE1_SGIS;
- }
- else
- {
- Com_Printf ("...ignoring GL_SGIS_multitexture\n" );
- }
- }
- else
- {
- Com_Printf ("...GL_SGIS_multitexture not found\n" );
- }
-
- GL_SetDefaultState();
-
- /*
- ** draw our stereo patterns
- */
- #if 0 // commented out until H3D pays us the money they owe us
- GL_DrawStereoPattern();
- #endif
-
- GL_InitImages ();
- Mod_Init ();
- R_InitParticleTexture ();
- Draw_InitLocal ();
-
- err = qglGetError();
- if ( err != GL_NO_ERROR )
- Com_Printf ("glGetError() = 0x%x\n", err);
-
- return 0;
- }
-
- /*
- ===============
- R_Shutdown
- ===============
- */
- void R_Shutdown (void)
- {
- Cmd_RemoveCommand ("modellist");
- Cmd_RemoveCommand ("screenshot");
- Cmd_RemoveCommand ("imagelist");
- Cmd_RemoveCommand ("gl_strings");
-
- Mod_FreeAll ();
-
- GL_ShutdownImages ();
-
- /*
- ** shut down OS specific OpenGL stuff like contexts, etc.
- */
- GLimp_Shutdown();
-
- /*
- ** shutdown our QGL subsystem
- */
- QGL_Shutdown();
- }
-
-
-
- /*
- @@@@@@@@@@@@@@@@@@@@@
- R_BeginFrame
- @@@@@@@@@@@@@@@@@@@@@
- */
- void R_BeginFrame( float camera_separation )
- {
-
- gl_state.camera_separation = camera_separation;
-
- /*
- ** change modes if necessary
- */
- if ( gl_mode->modified || vid_fullscreen->modified )
- { // FIXME: only restart if CDS is required
- cvar_t *ref;
-
- ref = Cvar_Get ("vid_ref", "gl", 0);
- ref->modified = true;
- }
-
- if ( gl_log->modified )
- {
- GLimp_EnableLogging( gl_log->value );
- gl_log->modified = false;
- }
-
- if ( gl_log->value )
- {
- GLimp_LogNewFrame();
- }
-
- /*
- ** update 3Dfx gamma -- it is expected that a user will do a vid_restart
- ** after tweaking this value
- */
- if ( vid_gamma->modified )
- {
- vid_gamma->modified = false;
-
- if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
- {
- char envbuffer[1024];
- float g;
-
- g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
- Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
- putenv( envbuffer );
- Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
- putenv( envbuffer );
- }
- }
-
- GLimp_BeginFrame( camera_separation );
-
- /*
- ** go into 2D mode
- */
- R_SetGL2D ();
-
- /*
- ** draw buffer stuff
- */
- if ( gl_drawbuffer->modified )
- {
- gl_drawbuffer->modified = false;
-
- if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled )
- {
- if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 )
- qglDrawBuffer( GL_FRONT );
- else
- qglDrawBuffer( GL_BACK );
- }
- }
-
- /*
- ** texturemode stuff
- */
- if ( gl_texturemode->modified )
- {
- GL_TextureMode( gl_texturemode->string );
- gl_texturemode->modified = false;
- }
-
- if ( gl_texturealphamode->modified )
- {
- GL_TextureAlphaMode( gl_texturealphamode->string );
- gl_texturealphamode->modified = false;
- }
-
- if ( gl_texturesolidmode->modified )
- {
- GL_TextureSolidMode( gl_texturesolidmode->string );
- gl_texturesolidmode->modified = false;
- }
-
- /*
- ** swapinterval stuff
- */
- GL_UpdateSwapInterval();
-
- //
- // clear screen if desired
- //
- R_Clear ();
- }
-
- /*
- =============
- R_AppActivate
- =============
- */
- void R_AppActivate( qboolean active )
- {
- GLimp_AppActivate (active);
- }
-
- /*
- =============
- R_EndFrame
- =============
- */
- void R_EndFrame (void)
- {
- GLimp_EndFrame ();
- }
-
- /*
- =============
- R_SetPalette
- =============
- */
- unsigned r_rawpalette[256];
-
- void R_SetPalette ( const unsigned char *palette)
- {
- int i;
-
- byte *rp = ( byte * ) r_rawpalette;
-
- if ( palette )
- {
- for ( i = 0; i < 256; i++ )
- {
- rp[i*4+0] = palette[i*3+0];
- rp[i*4+1] = palette[i*3+1];
- rp[i*4+2] = palette[i*3+2];
- rp[i*4+3] = 0xff;
- }
- }
- else
- {
- for ( i = 0; i < 256; i++ )
- {
- rp[i*4+0] = d_8to24table[i] & 0xff;
- rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff;
- rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff;
- rp[i*4+3] = 0xff;
- }
- }
- GL_SetTexturePalette( r_rawpalette );
-
- qglClearColor (0,0,0,0);
- qglClear (GL_COLOR_BUFFER_BIT);
- qglClearColor (1,0, 0.5 , 0.5);
- }
-
- /*
- ** R_DrawBeam
- */
- void R_DrawBeam( entity_t *e )
- {
- #define NUM_BEAM_SEGS 6
-
- int i;
- float r, g, b;
-
- vec3_t perpvec;
- vec3_t direction, normalized_direction;
- vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
- vec3_t oldorigin, origin;
-
- oldorigin[0] = e->oldorigin[0];
- oldorigin[1] = e->oldorigin[1];
- oldorigin[2] = e->oldorigin[2];
-
- origin[0] = e->origin[0];
- origin[1] = e->origin[1];
- origin[2] = e->origin[2];
-
- normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
- normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
- normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
-
- if ( VectorNormalize( normalized_direction ) == 0 )
- return;
-
- PerpendicularVector( perpvec, normalized_direction );
- VectorScale( perpvec, e->frame / 2, perpvec );
-
- for ( i = 0; i < 6; i++ )
- {
- RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
- VectorAdd( start_points[i], origin, start_points[i] );
- VectorAdd( start_points[i], direction, end_points[i] );
- }
-
- qglDisable( GL_TEXTURE_2D );
- qglEnable( GL_BLEND );
- qglDepthMask( GL_FALSE );
-
- r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF;
- g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF;
- b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF;
-
- r *= 1/255.0F;
- g *= 1/255.0F;
- b *= 1/255.0F;
-
- qglColor4f( r, g, b, e->alpha );
-
- qglBegin( GL_TRIANGLE_STRIP );
- for ( i = 0; i < NUM_BEAM_SEGS; i++ )
- {
- qglVertex3fv( start_points[i] );
- qglVertex3fv( end_points[i] );
- qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] );
- qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] );
- }
- qglEnd();
-
- qglEnable( GL_TEXTURE_2D );
- qglDisable( GL_BLEND );
- qglDepthMask( GL_TRUE );
- }
-
- // glow rendering - this was originally in gl_rmain.c
- void R_RenderGlowEffects (void)
- {
- int i, j, k;
- vec3_t v;
-
- // replace this with your own fog stuff if you're using fog
- // if (gl_fogenabled)
- // glDisable (GL_FOG);
-
- qglDepthMask (0);
- qglDisable (GL_TEXTURE_2D);
- qglShadeModel (GL_SMOOTH);
- qglEnable (GL_BLEND);
- qglBlendFunc (GL_ONE, GL_ONE);
-
- for (k = 0; k < num_glows; k++)
- {
- qglBegin (GL_TRIANGLE_FAN);
- qglColor3f (glow_effects[k].red, glow_effects[k].green, glow_effects[k].blue);
-
- for (i = 0; i < 3; i++)
- v[i] = glow_effects[k].origin[i] - vpn[i] * glow_effects[k].radius;
-
- qglVertex3fv (v);
- qglColor3f (0,0,0);
-
- for (i = 16; i >= 0; i--)
- {
- for (j = 0; j < 3; j++)
- v[j] = glow_effects[k].origin[j] + vright[j] * glowcos[i] *
- glow_effects[k].radius + vup[j] * glowsin[i] * glow_effects[k].radius;
-
- qglVertex3fv (v);
- }
-
- qglEnd ();
- }
-
- qglColor3f (1,1,1);
- qglDisable (GL_BLEND);
- qglEnable (GL_TEXTURE_2D);
- qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- qglDepthMask (1);
-
- // replace this with your own fog stuff if you're using fog
- // if (gl_fogenabled)
- // glEnable (GL_FOG);
- }
-
-
- void R_AddGlowEffect (float red, float green, float blue, float radius, vec3_t origin)
- {
- glow_effects[num_glows].red = red;
- glow_effects[num_glows].green = green;
- glow_effects[num_glows].blue = blue;
-
- glow_effects[num_glows].radius = radius;
-
- glow_effects[num_glows].origin[0] = origin[0];
- glow_effects[num_glows].origin[1] = origin[1];
- glow_effects[num_glows].origin[2] = origin[2];
-
- num_glows++;
- }
-